#ifndef BAS_BAS_ITERATOR_H
#define BAS_BAS_ITERATOR_H

#include <stdbool.h>
#include <stdlib.h>
#include "bas/bas_iterator_private.h"

/**
 * @note:
 *  输入迭代器支持的操作有:
 *      basIteratorGetValue
 *      basIteratorGetPointer
 *      basIteratorEqual
 *      basIteratorNext
 *  输出迭代器支持的操作有:
 *      basIteratorSetValue
 *      basIteratorNext
 *  前向迭代器支持的操作有:
 *      basIteratorGetValue
 *      basIteratorGetPointer
 *      basIteratorSetValue
 *      basIteratorEqual
 *      basIteratorNext
 *  双向迭代器支持的操作有:
 *      basIteratorGetValue
 *      basIteratorGetPointer
 *      basIteratorSetValue
 *      basIteratorEqual
 *      basIteratorPrev
 *      basIteratorNext
 *  随机迭代器支持的操作有:
 *      basIteratorGetValue
 *      basIteratorGetPointer
 *      basIteratorSetValue
 *      basIteratorEqual
 *      basIteratorPrev
 *      basIteratorNext
 *      basIteratorLess
 *      basIteratorLessEqual
 *      basIteratorGreat
 *      basIteratorGreatEqual
 *      basIteratorNextN
 *      basIteratorPrevN
 *      basIteratorMinus
 *
 */

/**
 * @brief      得到迭代器当前所指向位置的数据, 存放到value所指向的缓冲区中
 * @param[in]  tIterator 迭代器
 * @param[out] pvValue   输出缓冲区
 */
void basIteratorGetValue(const T_Iterator tIterator, void *pvValue);

/**
 * @brief     得到迭代器当前所指向位置的数据指针
 * @param[in] tIterator 迭代器
 * @returns   迭代器当前所指向位置的数据指针, 特别要注意BUILDIN_STRING类型, 返回值是(char *)的指针, 也就是(char **)
 * @warning   修改BUILDIN_STRING类型的返回值时, 请注意不能改变字符串长度, 否则将导致内存越界或者内存泄露
 */
void *basIteratorGetPointer(const T_Iterator tIterator);

/**
 * @brief     根据value所指向的缓冲区中的数据, 设置迭代器当前所指向位置的数据
 * @param[in] tIterator 迭代器
 * @param[in] pvValue   输入缓冲区
 * @warning   直接覆盖容器内的复杂类型值和BUILDIN_STRING将会导致内存泄露
 */
void basIteratorSetValue(T_Iterator tIterator, const void *pvValue);

/**
 * @brief     返回指向下一个位置的迭代器
 * @param[in] tIterator 迭代器
 * @returns   下一个位置的迭代器
 */
T_Iterator basIteratorNext(const T_Iterator tIterator);

/**
 * @brief     返回指向上一个位置的迭代器
 * @param[in] tIterator 迭代器
 * @returns   上一个位置的迭代器
 */
T_Iterator basIteratorPrev(const T_Iterator tIterator);

/**
 * @brief    判断两个迭代器的类型是否相同
 * @param[in] tFirstIterator  第一个迭代器
 * @param[in] tSecondIterator 第二个迭代器
 * @returns   true - 相同 false - 不相同
 */
bool basIteratorIsSameType(const T_Iterator tFirstIterator, const T_Iterator tSecondIterator);

/**
 * @brief     判断迭代器是否有效
 * @param[in] tIterator 迭代器
 * @returns   true - 有效 false - 无效
 */
bool basIteratorIsValid(const T_Iterator tIterator);

/**
 * @brief     判断两个迭代器是否相等
 * @param[in] tFirstIterator  第一个迭代器
 * @param[in] tSecondIterator 第二个迭代器
 * @returns   true - 相等 false - 不相等
 * @note      两个迭代器的类型必须相同
 */
bool basIteratorEqual(const T_Iterator tFirstIterator, const T_Iterator tSecondIterator);

/**
 * @brief     判断第一个迭代器是否小于第二个迭代器
 * @param[in] tFirstIterator  第一个迭代器
 * @param[in] tSecondIterator 第二个迭代器
 * @returns   true - 小于 false - 不小于
 * @note      两个迭代器的类型必须相同
 */
bool basIteratorLess(const T_Iterator tFirstIterator, const T_Iterator tSecondIterator);

/**
 * @brief     判断第一个迭代器是否小于等于第二个迭代器
 * @param[in] tFirstIterator  第一个迭代器
 * @param[in] tSecondIterator 第二个迭代器
 * @returns   true - 小于等于 false - 不小于等于
 * @note      两个迭代器的类型必须相同
 */
bool basIteratorLessEqual(const T_Iterator tFirstIterator, const T_Iterator tSecondIterator);

/**
 * @brief     判断第一个迭代器是否大于第二个迭代器
 * @param[in] tFirstIterator  第一个迭代器
 * @param[in] tSecondIterator 第二个迭代器
 * @returns   true - 大于 false - 不大于
 * @note      两个迭代器的类型必须相同
 */
bool basIteratorGreat(const T_Iterator tFirstIterator, const T_Iterator tSecondIterator);

/**
 * @brief     判断第一个迭代器是否大于等于第二个迭代器
 * @param[in] tFirstIterator  第一个迭代器
 * @param[in] tSecondIterator 第二个迭代器
 * @returns   true - 大于等于 false - 不大于等于
 * @note      两个迭代器的类型必须相同
 */
bool basIteratorGreatEqual(const T_Iterator tFirstIterator, const T_Iterator tSecondIterator);

/**
 * @brief     返回指向下nCount个位置的迭代器
 * @param[in] tIterator 迭代器
 * @returns   下nCount个位置的迭代器
 */
T_Iterator basIteratorNextN(const T_Iterator tIterator, const size_t nCount);

/**
 * @brief     返回指向上nCount个位置的迭代器
 * @param[in] tIterator 迭代器
 * @returns   上nCount个位置的迭代器
 */
T_Iterator basIteratorPrevN(const T_Iterator tIterator, const size_t nCount);

/**
 * @brief     返回两个迭代器的差
 * @param[in] tFirstIterator  第一个迭代器
 * @param[in] tSecondIterator 第二个迭代器
 * @returns   两个迭代器的差
 * @note      两个迭代器的类型必须相同
 */
int basIteratorMinus(const T_Iterator tFirstIterator, const T_Iterator tSecondIterator);

/**
 * 通过迭代器取元素的域段
 */
#define BAS_ITER_GET_FIELD(_tIterator, _T_Type, _fieldName) \
    (((_T_Type *)basIteratorGetPointer(_tIterator))->_fieldName)

#endif
